import { useState, useEffect, useRef } from 'react'
/* -------------------------------------------------------- antd -- */
import { Cascader } from 'antd'
/* -------------------------------------------------------- Declare -- */
const { $fn, $config, $http } = window
/* -------------------------------------------------------- 回到顶部 -- */
const Index = ({ 
	className,						/** @param {String}				# 盒子 className */
	style, 							/** @param {String}				# 盒子 style */
	// size='small', 					/** @param {String}				# 大小 */
	// name, 							/** @param {String}				# name */
	p,								/** @param {String}				# 提示语 */
	hint='请选择',					/** @param {String}				# 提示语 */
	label='',						/** @param {String}				# 标签名 */
	width,							/** @param {String}				# 宽度 */
	out,							/** @param {Number}				# 在外部设置 value */
	//
	value,							/** @param {String}				# 值 */
	disabled,						/** @param {Boolan}				# 禁用 */
	allowClear=true,				/** @param {Boolan}				# 显示清除按钮 */
	// 获取值
	onChange,						/** @param {Event}				# 有 Form 时值改变时执行 */
	onChanged,						/** @param {Event}				# 值改变时执行 */
	// 自定义扩展
	antd = {},						/** @param {Object}				# antd */
	// data
	api=['dict/area/province','dict/area/city','dict/area/country','dict/area/street'], /** @param {String}				# 获取数据的 api */
	level,							/** @param {Object}				# 选择级数 */
	param,							/** @param {Object}				# api 参数 */
	data,							/** @param {Array}				# 数据 */
	idStr=$config.idStr,			/** @param {String}				# 提交字段名 */
	nameStr=$config.nameStr,		/** @param {String}				# 显示字段名 */
	cache,							/** @param {Boolan}				# 是否缓存 */
	onlyId,							/** @param {Boolan}				# 返回值是否包括文本，仅是 id 值 */
}, ref)=> {// eslint-disable-line
	const onceRef = useRef(0)
	const valueRef = useRef([])
	let [ model, setModel ] = useState(value??'')
	let [ ajax, setAjax ] = useState( data )
	
	if( level ) {
		api = api.filter((_,i) => i < level )
	}
	
	p = p ? p : hint + label
	let isLazy = Array.isArray(api)
	// className = `jzer-select-${size} ${$.css(className)}`
	antd = { 
		className, disabled, allowClear, 
		value: model,
		placeholder: p, 
		showSearch:!isLazy,
		changeOnSelect: isLazy,
		fieldNames: { label:nameStr, value: idStr, children:'children' },	// 自定义字段
		options : ajax,
		style: { minWidth:width, ...style, height:500},
		// dropdownMenuColumnStyle: {},		// 选择列表单列样式
		...antd
	}
	
	// useEffect(() => {
	// 	$fn.ajax({setAjax, data:ajax, api: Array.isArray(api) ? api[0] : api, cache, paging, param})
	// }, []) // eslint-disable-line
	
	const backapi = (ajax, arr) => {
		let value = $fn.deepCopy(arr)
		let i = 0
		
		const deep = async rows => {
			if( i === 0 ){
				if(!$fn.hasArray(ajax)){
					ajax = await $fn.ajax({setAjax:null, data:ajax, api: Array.isArray(api) ? api[i] : api, cache, param})
				}
				if( value.length > 1 ) { 
					i++
					deep(ajax)
				} else { 
					setAjax([...ajax])
				}
			}else{
				if(onceRef.current===0 && $fn.hasArray(value)){
					if(api?.[i]){
						let parent = value[i-1];
						$http.pull(null, api[i], { id: parent }).then(data=>{
							if( !$fn.hasArray( data ) ) return
							for(let k in rows ){
								const p = rows[k]
								if(p.value === parent ){
									p.children = data
									if(value.length-1 === i){
										setAjax([...ajax])
									}else{
										i++
										deep( p.children )
									}
									break
								}
							}
						})
					}
				}
			}
		}
		deep(ajax)
	}
	
	useEffect(()=> { 
		if( !out ) {
			valueRef.current = value
			if( $fn.hasObject(valueRef.current?.[0]) && !onlyId ){
				valueRef.current = value.map( ({ value }) => value )
			}
			backapi(ajax, valueRef.current)
			setModel( valueRef.current )
		}
	}, [ value ]) // eslint-disable-line
	
	const _onChange = (value, option ) => {
		onceRef.current = 1;
		if(!out){ setModel( value ) }
		onChange?.( onlyId ? value : option )
		onChanged?.({ value, option })
	}
	
	const loadData = $fn.hasArray(api) ? option => {
		const d = option[option.length - 1];
		window.$http.pull(null, api[d.level], { id: d.value }).then( data =>{
			if( level && d.level === level - 1) data.forEach(v => v.isLeaf = 1) // level 确定显示层级
			d.children = data;
			setAjax([...ajax])
		})
	} : null
	
	return  <Cascader onChange={_onChange} {...antd} loadData={loadData}/>
}

export default Index